package com.minimalist.common.entity.lindi.vo.tradeapplicationcredit;

import cn.hutool.core.date.DatePattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.minimalist.common.entity.basic.vo.file.FileVO;
import com.minimalist.common.utils.Add;
import com.minimalist.common.utils.Update;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 林地指标交易平台_交易申请付款凭证实体
 * <p>
 * 用于管理林地指标交易申请的付款凭证信息，包括付款金额、付款方式、
 * 收款方、交易流水号等相关信息，支持文件附件关联
 *
 * @author 11987
 */
@Schema(name = "林地指标交易平台_交易申请付款凭证实体")
public class LindiTradeApplicationCreditVO implements Serializable {
    
    @Serial
    private static final long serialVersionUID = 1L;

    // ========== 主要业务字段 ==========
    
    /**
     * 付款凭证ID
     */
    @NotNull(message = "付款凭证ID不能为空", groups = {Update.class})
    @JsonSerialize(using = ToStringSerializer.class)
    @Schema(name = "creditId", description = "付款凭证ID", type = "string")
    private Long creditId;

    /**
     * 交易申请ID
     */
    @NotNull(message = "交易申请ID不能为空", groups = {Add.class, Update.class})
    @JsonSerialize(using = ToStringSerializer.class)
    @Schema(name = "tradeApplicationId", description = "交易申请ID", type = "string")
    private Long tradeApplicationId;

    /**
     * 付款凭证名称
     */
    @NotBlank(message = "付款凭证名称不能为空", groups = {Add.class, Update.class})
    @Schema(name = "creditName", description = "付款凭证名称", type = "string")
    private String creditName;

    /**
     * 付款金额
     */
    @NotBlank(message = "付款金额不能为空", groups = {Add.class, Update.class})
    @Schema(name = "creditAmount", description = "付款金额", type = "string")
    private String creditAmount;

    /**
     * 付款日期
     */
    @Schema(name = "creditDate", description = "付款日期", type = "string")
    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    private LocalDateTime creditDate;

    /**
     * 付款方式
     */
    @Schema(name = "creditType", description = "付款方式", type = "string")
    private String creditType;

    /**
     * 收款方
     */
    @Schema(name = "creditPayee", description = "收款方", type = "string")
    private String creditPayee;

    /**
     * 交易流水号
     */
    @Schema(name = "creditCode", description = "交易流水号", type = "string")
    private String creditCode;

    /**
     * 备注
     */
    @Schema(name = "remark", description = "备注", type = "string")
    private String remark;

    // ========== 文件关联字段 ==========
    
    /**
     * 付款凭证文件ID
     */
    @JsonSerialize(using = ToStringSerializer.class)
    @Schema(name = "creditFileId", description = "付款凭证文件ID", type = "string")
    private Long creditFileId;

    /**
     * 付款凭证文件
     */
    @Schema(name = "creditFile", description = "付款凭证文件", type = "object")
    private FileVO creditFile;

    // ========== 审计字段 ==========
    
    /**
     * 创建人ID
     */
    @JsonSerialize(using = ToStringSerializer.class)
    @Schema(name = "createId", description = "创建人ID", type = "string")
    private Long createId;

    /**
     * 创建人姓名
     */
    @Schema(name = "createName", description = "创建人姓名", type = "string")
    private String createName;

    /**
     * 创建时间
     */
    @Schema(name = "createTime", description = "创建时间", type = "string")
    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    private LocalDateTime createTime;

    /**
     * 更新人ID
     */
    @JsonSerialize(using = ToStringSerializer.class)
    @Schema(name = "updateId", description = "更新人ID", type = "string")
    private Long updateId;

    /**
     * 更新人姓名
     */
    @Schema(name = "updateName", description = "更新人姓名", type = "string")
    private String updateName;

    /**
     * 更新时间
     */
    @Schema(name = "updateTime", description = "更新时间", type = "string")
    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
    private LocalDateTime updateTime;

    // ========== 构造函数 ==========
    
    /**
     * 默认构造函数
     */
    public LindiTradeApplicationCreditVO() {
    }

    /**
     * 全参数构造函数
     *
     * @param creditId            付款凭证ID
     * @param tradeApplicationId  交易申请ID
     * @param creditName          付款凭证名称
     * @param creditAmount        付款金额
     * @param creditDate          付款日期
     * @param creditType          付款方式
     * @param creditPayee         收款方
     * @param creditCode          交易流水号
     * @param remark              备注
     * @param creditFileId        付款凭证文件ID
     * @param creditFile          付款凭证文件
     * @param createId            创建人ID
     * @param createName          创建人姓名
     * @param createTime          创建时间
     * @param updateId            更新人ID
     * @param updateName          更新人姓名
     * @param updateTime          更新时间
     */
    public LindiTradeApplicationCreditVO(Long creditId, Long tradeApplicationId, String creditName, 
                                        String creditAmount, LocalDateTime creditDate, String creditType, 
                                        String creditPayee, String creditCode, String remark, 
                                        Long creditFileId, FileVO creditFile, Long createId, 
                                        String createName, LocalDateTime createTime, Long updateId, 
                                        String updateName, LocalDateTime updateTime) {
        this.creditId = creditId;
        this.tradeApplicationId = tradeApplicationId;
        this.creditName = creditName;
        this.creditAmount = creditAmount;
        this.creditDate = creditDate;
        this.creditType = creditType;
        this.creditPayee = creditPayee;
        this.creditCode = creditCode;
        this.remark = remark;
        this.creditFileId = creditFileId;
        this.creditFile = creditFile;
        this.createId = createId;
        this.createName = createName;
        this.createTime = createTime;
        this.updateId = updateId;
        this.updateName = updateName;
        this.updateTime = updateTime;
    }

    /**
     * 基本信息构造函数
     *
     * @param tradeApplicationId 交易申请ID
     * @param creditName         付款凭证名称
     * @param creditAmount       付款金额
     * @param creditDate         付款日期
     * @param creditType         付款方式
     */
    public LindiTradeApplicationCreditVO(Long tradeApplicationId, String creditName, String creditAmount, 
                                        LocalDateTime creditDate, String creditType) {
        this.tradeApplicationId = tradeApplicationId;
        this.creditName = creditName;
        this.creditAmount = creditAmount;
        this.creditDate = creditDate;
        this.creditType = creditType;
    }

    // ========== Getter 和 Setter 方法 ==========
    
    public Long getCreditId() {
        return creditId;
    }

    public void setCreditId(Long creditId) {
        this.creditId = creditId;
    }

    public Long getTradeApplicationId() {
        return tradeApplicationId;
    }

    public void setTradeApplicationId(Long tradeApplicationId) {
        this.tradeApplicationId = tradeApplicationId;
    }

    public String getCreditName() {
        return creditName;
    }

    public void setCreditName(String creditName) {
        this.creditName = creditName;
    }

    public String getCreditAmount() {
        return creditAmount;
    }

    public void setCreditAmount(String creditAmount) {
        this.creditAmount = creditAmount;
    }

    public LocalDateTime getCreditDate() {
        return creditDate;
    }

    public void setCreditDate(LocalDateTime creditDate) {
        this.creditDate = creditDate;
    }

    public String getCreditType() {
        return creditType;
    }

    public void setCreditType(String creditType) {
        this.creditType = creditType;
    }

    public String getCreditPayee() {
        return creditPayee;
    }

    public void setCreditPayee(String creditPayee) {
        this.creditPayee = creditPayee;
    }

    public String getCreditCode() {
        return creditCode;
    }

    public void setCreditCode(String creditCode) {
        this.creditCode = creditCode;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Long getCreditFileId() {
        return creditFileId;
    }

    public void setCreditFileId(Long creditFileId) {
        this.creditFileId = creditFileId;
    }

    public FileVO getCreditFile() {
        return creditFile;
    }

    public void setCreditFile(FileVO creditFile) {
        this.creditFile = creditFile;
    }

    public Long getCreateId() {
        return createId;
    }

    public void setCreateId(Long createId) {
        this.createId = createId;
    }

    public String getCreateName() {
        return createName;
    }

    public void setCreateName(String createName) {
        this.createName = createName;
    }

    public LocalDateTime getCreateTime() {
        return createTime;
    }

    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    public Long getUpdateId() {
        return updateId;
    }

    public void setUpdateId(Long updateId) {
        this.updateId = updateId;
    }

    public String getUpdateName() {
        return updateName;
    }

    public void setUpdateName(String updateName) {
        this.updateName = updateName;
    }

    public LocalDateTime getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }

    // ========== Object 方法重写 ==========
    
    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        
        LindiTradeApplicationCreditVO that = (LindiTradeApplicationCreditVO) o;
        
        return Objects.equals(creditId, that.creditId) &&
               Objects.equals(tradeApplicationId, that.tradeApplicationId) &&
               Objects.equals(creditName, that.creditName) &&
               Objects.equals(creditAmount, that.creditAmount) &&
               Objects.equals(creditDate, that.creditDate) &&
               Objects.equals(creditType, that.creditType) &&
               Objects.equals(creditPayee, that.creditPayee) &&
               Objects.equals(creditCode, that.creditCode) &&
               Objects.equals(remark, that.remark) &&
               Objects.equals(creditFileId, that.creditFileId) &&
               Objects.equals(creditFile, that.creditFile) &&
               Objects.equals(createId, that.createId) &&
               Objects.equals(createName, that.createName) &&
               Objects.equals(createTime, that.createTime) &&
               Objects.equals(updateId, that.updateId) &&
               Objects.equals(updateName, that.updateName) &&
               Objects.equals(updateTime, that.updateTime);
    }

    @Override
    public int hashCode() {
        return Objects.hash(creditId, tradeApplicationId, creditName, creditAmount, creditDate, 
                           creditType, creditPayee, creditCode, remark, creditFileId, creditFile, 
                           createId, createName, createTime, updateId, updateName, updateTime);
    }

    @Override
    public String toString() {
        return "LindiTradeApplicationCreditVO{" +
               "creditId=" + creditId +
               ", tradeApplicationId=" + tradeApplicationId +
               ", creditName='" + creditName + '\'' +
               ", creditAmount='" + creditAmount + '\'' +
               ", creditDate=" + creditDate +
               ", creditType='" + creditType + '\'' +
               ", creditPayee='" + creditPayee + '\'' +
               ", creditCode='" + creditCode + '\'' +
               ", remark='" + remark + '\'' +
               ", creditFileId=" + creditFileId +
               ", creditFile=" + creditFile +
               ", createId=" + createId +
               ", createName='" + createName + '\'' +
               ", createTime=" + createTime +
               ", updateId=" + updateId +
               ", updateName='" + updateName + '\'' +
               ", updateTime=" + updateTime +
               '}';
    }

    // ========== Builder 模式 ==========
    
    /**
     * 创建Builder实例
     *
     * @return Builder实例
     */
    public static LindiTradeApplicationCreditVOBuilder builder() {
        return new LindiTradeApplicationCreditVOBuilder();
    }

    /**
     * Builder类，用于构建LindiTradeApplicationCreditVO实例
     */
    public static class LindiTradeApplicationCreditVOBuilder {
        private Long creditId;
        private Long tradeApplicationId;
        private String creditName;
        private String creditAmount;
        private LocalDateTime creditDate;
        private String creditType;
        private String creditPayee;
        private String creditCode;
        private String remark;
        private Long creditFileId;
        private FileVO creditFile;
        private Long createId;
        private String createName;
        private LocalDateTime createTime;
        private Long updateId;
        private String updateName;
        private LocalDateTime updateTime;

        LindiTradeApplicationCreditVOBuilder() {
        }

        public LindiTradeApplicationCreditVOBuilder creditId(Long creditId) {
            this.creditId = creditId;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder tradeApplicationId(Long tradeApplicationId) {
            this.tradeApplicationId = tradeApplicationId;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditName(String creditName) {
            this.creditName = creditName;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditAmount(String creditAmount) {
            this.creditAmount = creditAmount;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditDate(LocalDateTime creditDate) {
            this.creditDate = creditDate;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditType(String creditType) {
            this.creditType = creditType;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditPayee(String creditPayee) {
            this.creditPayee = creditPayee;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditCode(String creditCode) {
            this.creditCode = creditCode;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder remark(String remark) {
            this.remark = remark;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditFileId(Long creditFileId) {
            this.creditFileId = creditFileId;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder creditFile(FileVO creditFile) {
            this.creditFile = creditFile;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder createId(Long createId) {
            this.createId = createId;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder createName(String createName) {
            this.createName = createName;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder createTime(LocalDateTime createTime) {
            this.createTime = createTime;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder updateId(Long updateId) {
            this.updateId = updateId;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder updateName(String updateName) {
            this.updateName = updateName;
            return this;
        }

        public LindiTradeApplicationCreditVOBuilder updateTime(LocalDateTime updateTime) {
            this.updateTime = updateTime;
            return this;
        }

        public LindiTradeApplicationCreditVO build() {
            return new LindiTradeApplicationCreditVO(creditId, tradeApplicationId, creditName, 
                                                    creditAmount, creditDate, creditType, creditPayee, 
                                                    creditCode, remark, creditFileId, creditFile, 
                                                    createId, createName, createTime, updateId, 
                                                    updateName, updateTime);
        }

        @Override
        public String toString() {
            return "LindiTradeApplicationCreditVO.LindiTradeApplicationCreditVOBuilder{" +
                   "creditId=" + creditId +
                   ", tradeApplicationId=" + tradeApplicationId +
                   ", creditName='" + creditName + '\'' +
                   ", creditAmount='" + creditAmount + '\'' +
                   ", creditDate=" + creditDate +
                   ", creditType='" + creditType + '\'' +
                   ", creditPayee='" + creditPayee + '\'' +
                   ", creditCode='" + creditCode + '\'' +
                   ", remark='" + remark + '\'' +
                   ", creditFileId=" + creditFileId +
                   ", creditFile=" + creditFile +
                   ", createId=" + createId +
                   ", createName='" + createName + '\'' +
                   ", createTime=" + createTime +
                   ", updateId=" + updateId +
                   ", updateName='" + updateName + '\'' +
                   ", updateTime=" + updateTime +
                   '}';
        }
    }
}
